classdef Butterworth < FilterFather
    properties
        NormalizedPoles = [];
    end
    
    methods
        
        function this = Butterworth(guiData)
            this.calculateFilter(guiData);
            minEdge = min([guiData.Fp guiData.Fa])*2*pi;
            maxEdge = max([guiData.Fp guiData.Fa])*2*pi;
            if this.Order <= 25
                this.calcData([minEdge maxEdge]);
            end
        end
        
        function calculateFilter(obj,guiData)
            
            Aa = guiData.Aa;
            Ap = guiData.Ap;
            obj.Approximation = 'Butterworth';
            obj.FilterType = guiData.filterType;
            Wp = guiData.Fp*2*pi;
            Wa = guiData.Fa*2*pi;
            [Wp Wa] = obj.adjustBand(Wp,Wa);
            obj.DesnormValue = guiData.DenormVal;
            obj.DesnormType = guiData.DenormType;
            fixOrder = guiData.fixOrder;
            MaxOrder = guiData.order;
            
%             MaxQ = guiData.maxQ;
            
            obj.normalization(Wp,Wa);
            
            epsilon = sqrt(10^(.1*abs(Ap))-1);

            % Order calculus
            N = ceil(log10( sqrt(10.^(.1*abs(Aa))-1)./epsilon ) / log10(obj.WaNormalized) );
          
            if MaxOrder == 0
                obj.Order = N;
            else 
                if(N > MaxOrder || fixOrder == true)
                    N = MaxOrder;
                end
                obj.Order = N;
            end
            
            
            
%             if obj.Order > MaxOrder
%                 obj.Order = MaxOrder;
%             end
            if obj.Order <= 25
                [x y] = pol2cart(pi*(1:2:N-1)/(2*N) + pi/2,1);
                p = [x+1i*y , x-1i*y]; % To sort numerical errors
                p = p(:);   %Convert in a vertical matrix
                if rem(N,2)==1   % if N is odd
                    p = [p; -1];    % The negative real pole
                end
                p = p/nthroot(epsilon,N);
                obj.NormalizedPoles = p;
                obj.Poles = p;
                obj.Zeros = [];
                obj.K = abs(prod(obj.Poles));
                obj.frecDesnorm(Aa);
                obj.K = abs(prod(obj.Poles));	
                obj.desnormalization();
                obj.TransferFunction = obj.TransferFunction*10^(guiData.gain/20);
            end
        end
    end
end